/*
 * @Author: Clark
 * @Email: haixuanwoTxh@gmail.com
 * @Date: 2023-01-28 16:00:43
 * @LastEditors: Clark
 * @LastEditTime: 2023-01-28 16:20:14
 * @Description: file content
 */
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>

extern char **environ;
pthread_mutex_t env_mutex;
static pthread_once_t init_done = PTHREAD_ONCE_INIT;

static void thread_init(void)
{
    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&env_mutex, &attr);
    pthread_mutexattr_destroy(&attr);
}

int getenv_r(const char *name, char *buf, int buflen)
{
    pthread_once(&init_done, thread_init);
    int len = strlen(name);

    pthread_mutex_lock(&env_mutex);
    for (size_t i = 0; NULL != environ[i]; i++)
    {
        if ((strncmp(name, environ[i], len) == 0) && ('=' == environ[i][len]))
        {
            int olen = strlen(&environ[i][len+1]);
            if (olen >= buflen)
            {
                pthread_mutex_unlock(&env_mutex);
                return ENOSPC;
            }

            strcpy(buf, &environ[i][len+1]);
            pthread_mutex_unlock(&env_mutex);
            return 0;
        }
    }

    pthread_mutex_unlock(&env_mutex);
    return ENOENT;
}
